Skip to content

[Enhancement](ai_func) Skip Null inputs in AI functions - #66242

Open
linrrzqqq wants to merge 1 commit into
apache:masterfrom
linrrzqqq:ai-func-skip-null
Open

[Enhancement](ai_func) Skip Null inputs in AI functions#66242
linrrzqqq wants to merge 1 commit into
apache:masterfrom
linrrzqqq:ai-func-skip-null

Conversation

@linrrzqqq

@linrrzqqq linrrzqqq commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Problem Summary:

The framework's default NULL implementation unwraps Nullable arguments and executes AI functions for every input row. For partially NULL inputs, the nested placeholder values of NULL rows are still included in prompts and sent to external AI providers.

This causes unnecessary remote requests and token consumption. It also requires special handling for embedding results to preserve the original row order without duplicating large embedding vectors.

This PR:

  • Disables the framework's default NULL implementation for all AIFunction subclasses.
  • Determines the Nullable return type in the AIFunction base class.
  • Extracts nested prompt columns and merges argument null maps in the common AI execution path.
  • Skips NULL rows before building prompts or sending requests.
  • Restores NULL rows in the final result while preserving the original row order.
  • Handles both text and multimodal Nullable inputs for EMBED.
  • Expands embedding array offsets in place, avoiding a copy of the nested Float32 embedding data.
  • Returns a constant NULL column when all input rows are NULL.

Release note

Fix AI scalar functions to skip NULL input rows instead of sending their placeholder values to external AI providers.

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Request changes. The compact prompt/result mapping is functionally sound for nullable scalar arguments, and the reverse embedding-offset expansion preserves row order without copying nested vectors. Two issues remain: a legal NULL resource literal can now reach a BE DORIS_CHECK instead of propagating NULL (MAIN-002), and nullable scalar blocks with an all-zero null map unnecessarily duplicate every result (MAIN-001).

Critical checkpoint conclusions: The change is focused and covers scalar, text-embedding, and multimodal-embedding paths. There is no production concurrency, special lifecycle, configuration, persistence, transaction, storage-format, or protocol change. Return-type and overload dispatch are otherwise consistent, and provider result-count validation protects compact-row reconstruction. Tests cover partial NULLs, merged argument maps, nullable array prompts, all-NULL constants, multimodal inputs, and batch boundaries, but they miss the NULL resource and all-zero-map cases above. No extra user review focus was supplied. Per the runner instruction, this was a static review and no local build or test command was run.

Comment thread be/src/exprs/function/ai/ai_functions.h
Comment thread be/src/exprs/function/ai/ai_functions.h
@linrrzqqq
linrrzqqq force-pushed the ai-func-skip-null branch from e02787a to 0d75fc4 Compare July 29, 2026 18:19
@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up review of 0d75fc43b7c12316bb6345091562fe9d64aa4c4b: I found no remaining blocking issue. The two previously raised concerns are addressed at this head: an all-NULL resource now returns before resource lookup, and a nullable input with an all-zero null map wraps the existing result directly instead of scattering and copying every result.

Critical checkpoint conclusions:

  • Goal and correctness: The change skips NULL prompt rows for all scalar AI functions and for both text and multimodal EMBED. Provider response counts are checked before reconstruction; scalar results are scattered in original row order, and embedding offsets are expanded in place without copying the nested Float32 vectors.
  • Scope and parallel paths: The change is focused on NULL propagation and compact execution. The common scalar path, String/Bool/Float result types, text embedding, multimodal embedding, constant inputs, multiple nullable arguments, all-NULL blocks, and all-zero null maps are covered.
  • Nullable and compatibility contracts: ColumnConst(ColumnNullable) handling follows the function framework's constant path, BE return nullability matches FE PropagateNullable, and EMBED preserves its Array<Nullable<Float32>> element type. There is no storage, protocol, persistence, rolling-upgrade, or function-symbol compatibility change.
  • Concurrency, lifecycle, configuration, and data writes: There is no new production concurrency, shared mutable lifecycle, configuration item, transaction/persistence behavior, or data-write path. The test-only adapter capture is thread-local.
  • Performance: NULL rows no longer consume provider requests or tokens; the scalar all-zero fast path avoids a full result copy, and the embedding path rewrites only offsets while retaining the nested vector buffer.
  • Testing: BE unit coverage was added for partial NULLs, merged argument null maps, String/Bool/Float and nullable-array inputs, all-NULL constants, NULL resources, all-zero maps, text and multimodal embeddings, and batch boundaries. Per the review-runner instruction, I did not run builds or tests locally.

No additional user-provided review focus was supplied. Review completion is confirmed for the current head.

@linrrzqqq

Copy link
Copy Markdown
Collaborator Author

run buildall

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29434 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit 0d75fc43b7c12316bb6345091562fe9d64aa4c4b, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17828	4068	4052	4052
q2	2020	311	189	189
q3	10288	1399	839	839
q4	4716	462	350	350
q5	7788	821	569	569
q6	243	168	134	134
q7	748	823	597	597
q8	10389	1462	1524	1462
q9	5734	4293	4308	4293
q10	6818	1728	1467	1467
q11	513	345	318	318
q12	741	585	469	469
q13	18101	3345	2734	2734
q14	266	265	249	249
q15	q16	781	776	710	710
q17	1070	989	1028	989
q18	6737	5684	5604	5604
q19	1662	1214	1138	1138
q20	816	648	565	565
q21	5830	2618	2415	2415
q22	422	347	291	291
Total cold run time: 103511 ms
Total hot run time: 29434 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4396	4332	4329	4329
q2	278	314	207	207
q3	4606	4885	4426	4426
q4	2032	2109	1348	1348
q5	4380	4240	4220	4220
q6	226	175	126	126
q7	1703	2187	1639	1639
q8	2428	2187	2075	2075
q9	7684	7732	7688	7688
q10	4709	4669	4207	4207
q11	550	422	551	422
q12	730	763	534	534
q13	3259	3622	2888	2888
q14	323	320	266	266
q15	q16	718	722	622	622
q17	1340	1275	1291	1275
q18	7991	7317	6693	6693
q19	1080	1052	1117	1052
q20	2200	2192	1922	1922
q21	5143	4482	4309	4309
q22	493	456	413	413
Total cold run time: 56269 ms
Total hot run time: 50661 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 177519 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit 0d75fc43b7c12316bb6345091562fe9d64aa4c4b, data reload: false

query5	4343	629	490	490
query6	476	229	209	209
query7	4863	604	343	343
query8	342	187	171	171
query9	8753	4109	4027	4027
query10	472	359	301	301
query11	5836	2335	2167	2167
query12	159	108	105	105
query13	1275	664	440	440
query14	6235	5212	4967	4967
query14_1	4259	4238	4260	4238
query15	217	205	176	176
query16	1048	465	442	442
query17	1089	690	543	543
query18	2425	464	336	336
query19	203	182	144	144
query20	119	106	115	106
query21	240	156	139	139
query22	13539	13578	13314	13314
query23	17350	16519	16124	16124
query23_1	16260	16301	16239	16239
query24	7498	1734	1265	1265
query24_1	1266	1309	1281	1281
query25	531	437	353	353
query26	1321	363	209	209
query27	2634	639	378	378
query28	4433	2042	2054	2042
query29	1065	605	461	461
query30	345	263	225	225
query31	1126	1082	991	991
query32	100	59	56	56
query33	515	329	240	240
query34	1178	1121	659	659
query35	767	774	714	714
query36	1039	1042	899	899
query37	153	104	90	90
query38	1861	1698	1657	1657
query39	879	889	843	843
query39_1	825	836	831	831
query40	242	164	142	142
query41	64	61	63	61
query42	98	88	90	88
query43	318	321	280	280
query44	1476	792	773	773
query45	204	183	170	170
query46	1062	1253	735	735
query47	2133	2089	1967	1967
query48	415	404	303	303
query49	576	413	317	317
query50	1065	431	350	350
query51	10822	10696	10643	10643
query52	84	84	73	73
query53	264	276	204	204
query54	286	229	218	218
query55	72	70	65	65
query56	290	278	266	266
query57	1330	1282	1235	1235
query58	275	255	254	254
query59	1568	1662	1485	1485
query60	303	267	253	253
query61	154	153	148	148
query62	548	494	432	432
query63	248	205	202	202
query64	2814	1114	977	977
query65	4752	4667	4641	4641
query66	1844	521	403	403
query67	29448	29314	29155	29155
query68	3145	1558	989	989
query69	406	323	278	278
query70	912	881	830	830
query71	379	345	318	318
query72	3242	2875	2298	2298
query73	841	749	442	442
query74	5119	4909	4716	4716
query75	2536	2500	2130	2130
query76	2341	1167	750	750
query77	350	378	286	286
query78	11806	11867	11274	11274
query79	1474	1159	741	741
query80	1270	550	461	461
query81	570	333	286	286
query82	600	156	117	117
query83	380	321	297	297
query84	292	156	131	131
query85	945	625	549	549
query86	442	246	234	234
query87	1812	1823	1748	1748
query88	3797	2835	2826	2826
query89	442	375	330	330
query90	1853	194	193	193
query91	202	191	161	161
query92	63	57	52	52
query93	1720	1569	1022	1022
query94	731	347	320	320
query95	792	507	549	507
query96	1091	786	343	343
query97	2606	2615	2467	2467
query98	210	211	195	195
query99	1093	1109	991	991
Total cold run time: 263646 ms
Total hot run time: 177519 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.92 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit 0d75fc43b7c12316bb6345091562fe9d64aa4c4b, data reload: false

query1	0.01	0.01	0.00
query2	0.09	0.04	0.04
query3	0.25	0.13	0.14
query4	1.60	0.14	0.14
query5	0.23	0.22	0.23
query6	1.28	1.11	1.04
query7	0.03	0.01	0.01
query8	0.06	0.03	0.03
query9	0.37	0.30	0.31
query10	0.55	0.55	0.55
query11	0.20	0.13	0.13
query12	0.18	0.14	0.14
query13	0.47	0.47	0.48
query14	1.00	0.99	1.00
query15	0.64	0.58	0.60
query16	0.31	0.32	0.34
query17	1.12	1.09	1.05
query18	0.22	0.21	0.21
query19	2.00	1.93	1.97
query20	0.02	0.01	0.01
query21	15.42	0.19	0.13
query22	4.98	0.05	0.06
query23	16.11	0.30	0.12
query24	3.00	0.43	0.32
query25	0.11	0.05	0.04
query26	0.74	0.21	0.14
query27	0.05	0.03	0.03
query28	3.52	0.94	0.58
query29	12.51	4.18	3.32
query30	0.28	0.15	0.16
query31	2.76	0.59	0.31
query32	3.22	0.58	0.48
query33	3.25	3.21	3.18
query34	15.62	4.17	3.51
query35	3.50	3.48	3.55
query36	0.56	0.44	0.43
query37	0.09	0.06	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.19	0.15	0.14
query41	0.09	0.04	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.8 s
Total hot run time: 24.92 s

@hello-stephen

Copy link
Copy Markdown
Contributor

BE Regression && UT Coverage Report

Increment line coverage 100.00% (162/162) 🎉

Increment coverage report
Complete coverage report

Category Coverage
Function Coverage 75.70% (31965/42224)
Line Coverage 60.34% (356193/590298)
Region Coverage 56.85% (298369/524855)
Branch Coverage 58.34% (134556/230642)

@github-actions github-actions Bot added the approved Indicates a PR has been approved by one committer. label Jul 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR approved by at least one committer and no changes requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by one committer. dev/4.1.x

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants